#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "galois.h"
#include "galois_add.h"
#include <sys/time.h>

#define N 2
#define W 32

uint32_t *fxn_mod(uint32_t *two, uint32_t s)
{
	uint32_t *pp, high_bit, high_bit_r, *tmp, shift_count, inv;
	int i;

	pp = (uint32_t *) malloc(sizeof(uint32_t) * (N + 1));
	tmp = (uint32_t *) malloc(sizeof(uint32_t) * (N + 1));

	pp[N] = 1;
	pp[0] = 1;
	pp[1] = s;

	/* will need to change for k == 4 */
	high_bit = high_bit_r = 2;

	while (high_bit >= high_bit_r) {
		for (i = 0; i < N+1; i++) tmp[i] = pp[i];
		
		shift_count = high_bit - high_bit_r;

		inv = galois_single_divide(two[high_bit], tmp[high_bit_r], W);
		for (i = 0; i < 3; i++) tmp[i] = galois_single_multiply(inv, tmp[i], W);

		for (i = 0; i <= high_bit_r; i++) two[i] ^= tmp[i];
		while (two[high_bit] == 0) high_bit--;
	}

	free(tmp); free(pp);
	return two;
}

int fxn_gcd(uint32_t *two, uint32_t s)
{
	
}

main(int argc, char **argv)
{
	uint64_t s, one;
	int i, j, k, reducible;
	uint32_t *two;

	for (s = 2; s < (one << 32) - 1; s++) { // f = x^2 + sx + 1
		printf("s: %d\n", s);
		reducible = 1;
		for (i = 1; i <= N/2; i++) { //only one value for k==2, 2 for k == 4
			/* get (x ^ q ^ i - x) % f */
			two = (uint32_t *) malloc(sizeof(int) * (2 * i + 1));

			for (j = 0; j < 2 * i + 1; j ++) {
				two[j] = 0;
			}

			two[1] = 1;
			two[2*i] = 1;

/*
			printf("First: ");
			for (j = 0; j < 2*i + 1; j++) printf("%3u", two[j]);
			printf("\n");
*/

			two = fxn_mod(two, s);

/*
			printf("Then: ");
			for (j = 0; j < 2*i + 1; j++) printf("%3u", two[j]);
			printf("\n");
*/
			
			k = fxn_gcd(two, s);

			if (k == 0) { reducible = 0; break; }
			free(two);
		}
	}
}
